<?php

namespace app\install\controller;

use Exception;
use PDO;
use support\Request;

class Index
{
    public $IN_INSTALL = true;
    protected $isNext = true;
    protected $insInfo = '';

    // 版权信息设置
    protected  $cfg_copyright = '© 2023 honc.fun';

    public function index(Request $request)
    {
        return '';
        set_time_limit(0);

        // 检测php版本号
        if (phpversion() < '8.0') {
            return response('很抱歉，由于您的PHP版本过低，不能安装本软件，为了系统功能全面可用，请升级到PHP8.0或更高版本再安装，谢谢！');
        }

        return $this->viewStep($this->getStep());
        try {

            $step = $this->step_1();
        } catch (Exception $e) {
            dump($e);
        }
        dump($step);
        return $step;
        return $this->step_0();

        return response('install');
    }




    public function viewStep($s)
    {
        dump($s);
        if ($s == 0) {
            return $this->step_0();
        }
        // 环境检测
        if ($s == 1) {
            return $this->step_1();
        }
        // 配置文件
        if ($s == 2) {
            return $this->step_2();
        }
        // 正在安装
        if ($s == 3) {
            return $this->step_3();
        }


        // 检测数据库信息
        if ($s == 63832) {
            $get = request()->get();
            $dbhost = $get['dbhost'] ?? '';
            $dbuser = $get['dbuser'] ?? '';
            $dbpwd = $get['dbpwd'] ?? '';
            $dbport = $get['dbport'] ?? '';
            try {
                $dsn = "mysql:host=$dbhost;port={$dbport};charset=utf8";
                $pdo = new PDO($dsn, $dbuser, $dbpwd);
                return 'true';
            } catch (Exception $e) {
                return 'false';
            }
        }
        // 安装完成
        if ($s == md5('done')) {
            require_once(INSTALL_PATH . '/templates/step_4.php');
            $fp = fopen(INSTALL_PATH . '/install.lock', 'w');
            fwrite($fp, '程序已正确安装，重新安装请删除本文件');
            fclose($fp);
            exit();
        }
    }

    public function json(Request $request)
    {
        return json(['code' => 0, 'msg' => 'ok']);
    }

    // 获取当前步骤
    protected  function getStep()
    {
        $s1 =  request()->get('s', 0);
        // 初始化参数
        $s2 =  request()->post('s', 0);
        // 如果有GET值则覆盖POST值
        if ($s1 > 0 && in_array($s1, [1, 63832, md5('done')])) {
            $s2 = $s1;
        }
        return $s2;
    }

    protected function step_0()
    {
        return view('step_0', ['cfg_copyright' => $this->cfg_copyright]);
    }

    protected function step_1()
    {
        $gdInfo = function_exists('gd_info') ? gd_info() : [];
        if (function_exists('disk_free_space')) {
            $disk = floor(disk_free_space('../') / (1024 * 1024)) . 'M';
        } else {
            $disk = 'unknow';
        }

        // // 获取检测的路径数据
        // $iswrite_array = $this->getIsWriteArray();
        // // 获取检测的函数数据
        // $exists_array = $this->getExistsFuncArray();
        // // 获取扩展要求数据
        // $extendArray = $this->getExtendArray();


        $data = [
            'php_v' => $this->getPHPVersion(),
            'gd_v' => data_get($gdInfo, 'GD Version'),
            'disk' => $disk,
            'upload' => get_cfg_var("upload_max_filesize") ?: '不允许上传附件',
            'iswrite_array' => $this->getIsWriteArray(),
            'exists_array' => $this->getExistsFuncArray(),
            'extendArray' => $this->getExtendArray(),
            // 'iswrite_array' => '',
            // 'exists_array' => '',
            // 'extendArray' => '',
            'isNext' => $this->isNext,
            'cfg_copyright' => $this->cfg_copyright,
        ];

        return view('step_1', $data);
    }

    protected function step_2()
    {
        return view('step_2', ['cfg_copyright' => $this->cfg_copyright]);
    }

    protected function step_3()
    {

        $post = request()->post();
        $ends = '';
        return view('step_3', ['cfg_copyright' => $this->cfg_copyright, 'insInfo' => $this->insInfo, 'ends' => $ends]);
        if ($post['s'] == 3) {
            // 初始化信息
            $dbhost = $post['dbhost'] ?? '';
            $dbname = $post['dbname'] ?? '';
            $dbuser = $post['dbuser'] ?? '';
            $dbpwd = $post['dbpwd'] ?? '';
            $dbport = $post['dbport'] ?? 3306;

            $testdata = $post['testdata'] ?? '';

            // 连接证数据库
            try {
                $dsn = "mysql:host={$dbhost};port={$dbport};charset=utf8";
                $pdo = new PDO($dsn, $dbuser, $dbpwd);
                $pdo->query("SET NAMES utf8"); // 设置数据库编码
            } catch (Exception $e) {
                $this->setError('数据库连接错误，请检查！');
                return view('step_3', ['cfg_copyright' => $this->cfg_copyright, 'insInfo' => $this->insInfo]);
            }

            // 查询数据库
            $res = $pdo->query('show Databases');

            // 遍历所有数据库，存入数组
            $dbnameArr = [];
            foreach ($res->fetchAll(PDO::FETCH_ASSOC) as $row) {
                $dbnameArr[] = $row['Database'];
            }

            // 检查数据库是否存在，没有则创建数据库
            if (!in_array(trim($dbname), $dbnameArr)) {
                if (!$pdo->exec("CREATE DATABASE `$dbname`")) {
                    $this->setError("创建数据库失败，请检查权限或联系管理员！");
                    return view('step_3', ['cfg_copyright' => $this->cfg_copyright, 'insInfo' => $this->insInfo]);
                }
            }
            ob_start();
            $response = view('step_3', ['cfg_copyright' => $this->cfg_copyright, 'insInfo' => $this->insInfo, 'ends' => $ends]);
            // dump($res->rawBody());
            $response = $response->withHeader('Content-Type', 'text/html')->withHeader('X-Accel-Buffering', 'no');

            // 设置响应内容

            // 手动发送响应
            // $response->send();
            // echo $res->rawBody();
            // 数据库创建完成，开始连接
            $pdo->query("USE `$dbname`");

            // 取出.env模板内容
            $config_str = $this->readDataFile('.env.tpl');

            // 进行替换
            $config_str = str_replace('~db_host~', $dbhost, $config_str);
            $config_str = str_replace('~db_name~', $dbname, $config_str);
            $config_str = str_replace('~db_user~', $dbuser, $config_str);
            $config_str = str_replace('~db_pwd~', $dbpwd, $config_str);
            $config_str = str_replace('~db_port~', $dbport, $config_str);
            $config_str = str_replace('~db_charset~', 'utf8', $config_str);

            // 将替换后的内容写入.env文件
            $fp = fopen(root_path() . '/.env', 'w');
            fwrite($fp, $config_str);
            fclose($fp);

            // 防止浏览器缓存
            $buffer = ini_get('output_buffering');
            echo str_repeat(' ', $buffer + 1);

            $this->setInsInfo("数据库连接文件创建完成！");
            ob_flush();
            flush();

            // 创建表结构
            $tbstruct = $this->readDataFile('install_struct.sql');
            $pdo->exec(trim($tbstruct));

            $this->setInsInfo("数据库结构导入完成！");
            ob_flush();
            flush();

            // 导入其他安装数据
            $data_str = $this->readDataFile('install_data.sql');
            $pdo->exec(trim($data_str));

            $this->setInsInfo("商城默认数据导入完成！");
            ob_flush();
            flush();

            // 查看是否需要安装测试数据
            if ($testdata == 'true') {
                $this->setInsInfo("正在加载测试数据！");
                ob_flush();
                flush();

                $sqlstr_file = $this->readDataFile('install_testdata.sql');
                $pdo->exec(trim($sqlstr_file));

                $this->setInsInfo("测试数据导入完成！");
                ob_flush();
                flush();
            }

            // 结束缓存区
            ob_end_flush();

            // 安装完成进行跳转
            $ends = '<script>setTimeout(function () { location.href="?s=' . md5('done') . '"; }, 2000)</script>';
        }
        return view('step_3', ['cfg_copyright' => $this->cfg_copyright, 'insInfo' => $this->insInfo, 'ends' => $ends]);
    }

    public function getPHPVersion()
    {
        $version = phpversion();
        list($major, $minor, $sub) = explode('.', $version);
        $versionInt =  intval($major * 10000 + $minor * 100 + $sub);

        if ($versionInt < 80000 || $versionInt >= 80100) {
            $this->setIsNext(false);
            return "<span class=\"col-red\"><strong>{$version}</strong> (请使用php8.0)</span>";
        } else {
            return "<span>{$version}</span>";
        }
    }
    protected function getIsWriteArray()
    {
        $farr = [
            '/.env',
            // '/data/',
            '/public/install/',
            '/public/uploads/',
            '/public/temp/',
        ];
        $rfarrtxt = '';
        foreach ($farr as $file) {
            $isw = is_writable(base_path() . $file);
            if ($isw === false) {
                $this->setIsNext(false);
            }
            // $rfarrtxt .= "<tr>";
            // $rfarrtxt .= '<td height="26" class="firstCol">' . $file . '()</td><td>可写</td>';
            // $rfarrtxt .= '<td class="endCol">' . ($isw ? '<span>可写</span>' : '<span class="col-red">不可写</span>') . '</td>';
            // $rfarrtxt .= "</tr>";
            $rfarr[] = [
                'f' => $file,
                's' => $isw,
                't' => $isw ? '<span>可写</span>' : '<span class="col-red">不可写</span>'
            ];
        }

        return $rfarr;
        // return $rfarrtxt;
    }
    // 获取检测的函数数据
    protected function getExistsFuncArray()
    {
        $farr = ['curl_init', 'bcadd', 'mb_substr', 'simplexml_load_string'];
        $rfarrtxt = '';
        foreach ($farr as $func) {
            $state = function_exists($func);
            if ($state === false) {
                $this->setIsNext(false);
            }

            // $rfarrtxt .= "<tr>";
            // $rfarrtxt .= '<td height="26" class="firstCol">' . $func . '()</td>';
            // $rfarrtxt .= '<td>' . ($state ? '支持' : '不支持') . '</td>';
            // $rfarrtxt .= '<td class="endCol">' . ($state ? '<span>无</span>' : '<span class="col-red">需安装</span>') . '</td>';
            // $rfarrtxt .= "</tr>";
            $rfarr[] = [
                'f' => $func,
                's' => $state,
                't' => $state ? '<span>无</span>' : '<span class="col-red">需安装</span>'
            ];
        }
        return $rfarr;
        // return $rfarrtxt;
    }

    // 获取扩展要求数据
    protected function getExtendArray()
    {
        $data = [
            [
                'name' => 'PDO Mysql',
                'status' => extension_loaded('PDO') && extension_loaded('pdo_mysql'),
            ],
            [
                'name' => 'Mysqlnd',
                'status' => extension_loaded('mysqlnd'),
            ],
            [
                'name' => 'JSON',
                'status' => extension_loaded('json')
            ],
            [
                'name' => 'Fileinfo',
                'status' => extension_loaded('fileinfo')
            ],
            [
                'name' => 'CURL',
                'status' => extension_loaded('curl'),
            ],
            [
                'name' => 'OpenSSL',
                'status' => extension_loaded('openssl'),
            ],
            [
                'name' => 'GD',
                'status' => extension_loaded('gd'),
            ],
            [
                'name' => 'BCMath',
                'status' => extension_loaded('bcmath'),
            ],
            [
                'name' => 'Mbstring',
                'status' => extension_loaded('mbstring'),
            ],
            [
                'name' => 'SimpleXML',
                'status' => extension_loaded('SimpleXML'),
            ],
        ];
        $rearrtxt = '';
        foreach ($data as $item) {
            !$item['status'] && $this->setIsNext(false);
            // $rearrtxt .= '<tr>';
            // $rearrtxt .= '<td height="26" class="firstCol">' . $item['name'] . '</td>';
            // $rearrtxt .= '<td>' . ($item['status'] ? '支持' : '不支持') . '</td>';
            // $rearrtxt .= '<td class="endCol">' . ($item['status'] ? '<span>无</span>' : '<span class="col-red">需安装</span>') . '</td>';
            // $rearrtxt .= '</tr>';
        }


        return $data;
        // return $rearrtxt;
    }


    // 设置是否允许下一步
    protected function setIsNext(bool $bool)
    {
        $this->isNext = $bool;
    }


    protected function setInsInfo($str, $isExit = false)
    {
        if ($isExit) {
            $this->insInfo = '<script>$("#install").append("' . $str . '<br>");</script>';
        } else {
            $this->insInfo .= '<script>$("#install").append("' . $str . '<br>");</script>';
        }
    }

    protected function setError($str)
    {
        $this->setError("<span class='col-red'>$str</span>", true);
    }

    protected function readDataFile(string $file)
    {
        return file_get_contents(public_path() . '/install/data/' . $file);
    }
}
